package com.chan.hook.app;

import android.annotation.TargetApi;
import android.app.Application;
import android.content.Context;
import android.os.Build;
import android.os.Handler;
import android.util.Log;

import com.chan.hook.am.AMSHook;
import com.chan.hook.handle.MessageHook;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * Created by chan on 16/4/8.
 */
public class HookApplication extends Application {

    @TargetApi(Build.VERSION_CODES.KITKAT)
    @Override
    protected void attachBaseContext(Context base) {
        super.attachBaseContext(base);

        try {
            //获得ActivityManagerNative
            Class<?> serviceManagerClz = Class.forName("android.app.ActivityManagerNative", false, getClassLoader());
            //获得ActivityManagerNative.getDefault静态方法
            Method getDefaultMethod = serviceManagerClz.getDeclaredMethod("getDefault");

            //获得原始的IActivityManager对象
            Object rawIActivityManagerInterface = getDefaultMethod.invoke(null);
            //我们自己的Hook的对象
            Object hookIActivityManagerInterface = Proxy.newProxyInstance(
                    getClassLoader(),
                    new Class[]{Class.forName("android.app.IActivityManager", false, getClassLoader())},
                    new AMSHook(rawIActivityManagerInterface)
            );

            //反射ActivityManagerNative的gDefault域
            Field gDefaultField = serviceManagerClz.getDeclaredField("gDefault");
            gDefaultField.setAccessible(true);
            Object gDefaultObject = gDefaultField.get(null);

            //他的类型是Singleton
            Class<?> singletonClz = Class.forName("android.util.Singleton", false, getClassLoader());

            //把他的mInstance域替换掉 成为我们自己的Hook对象
            Field mInstanceField = singletonClz.getDeclaredField("mInstance");
            mInstanceField.setAccessible(true);
            mInstanceField.set(gDefaultObject, hookIActivityManagerInterface);

            //获取activity thread的class
            Class<?> activityThreadClz = Class.forName("android.app.ActivityThread", false, getClassLoader());
            //获得currentActivityThread方法以获得其对象
            //具体的解析请参考 http://blog.csdn.net/u013022222/article/details/51114391
            Method method = activityThreadClz.getDeclaredMethod("currentActivityThread");
            Object activityThreadObject = method.invoke(null);

            //获得activity thread中的mH域
            Field mHField = activityThreadClz.getDeclaredField("mH");
            mHField.setAccessible(true);
            Object mHObject = mHField.get(activityThreadObject);

            //获得Handler中的mCallback域
            Field handlerCallbackField = Handler.class.getDeclaredField("mCallback");
            handlerCallbackField.setAccessible(true);
            //获得原来的mCallback对象
            Object callbackObject = handlerCallbackField.get(mHObject);

            //设置成我们自己的Callback对象
            Object hookHObject = new MessageHook(callbackObject, getClassLoader());
            handlerCallbackField.set(mHObject, hookHObject);
            System.out.println("end");
        } catch (ClassNotFoundException | IllegalAccessException |
                NoSuchMethodException | InvocationTargetException | NoSuchFieldException e) {
            e.printStackTrace();
        }
    }
}

//        Class<?> activityThreadClass = null;
//            //加载activity thread的class
//            activityThreadClass = Class.forName("android.app.ActivityThread", false, getClassLoader());
//
//            //找到方法currentActivityThread
//            Method method = activityThreadClass.getDeclaredMethod("currentActivityThread");
//            //由于这个方法是静态的，所以传入Null就行了
//            Object currentActivityThread = method.invoke(null);
//
//            //把之前ActivityThread中的mInstrumentation替换成我们自己的
//            Field field = activityThreadClass.getDeclaredField("mInstrumentation");
//            field.setAccessible(true);
//            Instrumentation instrumentation = (Instrumentation) field.get(currentActivityThread);
//            InstrumentationProxy instrumentationProxy = new InstrumentationProxy(instrumentation);
//            field.set(currentActivityThread, instrumentationProxy);



//try {
//        //获得ServiceManger的class
//        Class<?> serviceManager = Class.forName("android.os.ServiceManager", false, getClassLoader());
//        //找到getService静态方法
//        Method getService = serviceManager.getDeclaredMethod("getService", String.class);
//        //获得原始的binder对象
//        IBinder rawBinder = (IBinder) getService.invoke(null, CLIPBOARD_SERVICE);
//
//        //定制我们自己的IBinder对象
//        ProxyBinder proxyBinder = new ProxyBinder(rawBinder, this);
//        IBinder proxy = (IBinder) Proxy.newProxyInstance(getClassLoader(), new Class[]{IBinder.class},
//        proxyBinder);
//
//        //注入到ServiceManager的sCache中
//        Field field = serviceManager.getDeclaredField("sCache");
//        field.setAccessible(true);
//        Map<String, IBinder> map = (Map<String, IBinder>) field.get(null);
//        map.put(CLIPBOARD_SERVICE, proxy);
//        } catch (ClassNotFoundException | IllegalAccessException | NoSuchMethodException
//        | InvocationTargetException | NoSuchFieldException e) {
//        e.printStackTrace();
//        }